Puesto que la fase de investigación supuso un retraso importante en el comienzo de la implementación de la herramienta, decidimos realizar una planificación de nuestro desarrollo. El método de desarrollo que hemos aplicado es un desarrollo incremental. Este tipo de desarrollo nos ha permitido realizar una división del trabajo en diferentes fases, de forma que al final de cada una tuviéramos una versión estable de la herramienta, permitiéndonos así incluir nueva funcionalidad en la fase siguiente. Además, esta metodología de desarrollo nos permitió realizar un seguimiento claro de los objetivos que se iban cumpliendo y cuales no. Esto nos ofrecía mayor flexibilidad en cuanto a poder modificar ligeramente la fase siguiente del desarrollo, retrasando objetivos a fases posteriores que fueran menos críticos.

A continuación, se detallan las fases en que dividimos el proceso de desarrollo, indicando para cada una los objetivos marcados, objetivos logrados y conclusiones.

\begin{enumerate}

\item{\emph{Fase preliminar: Prototipo básico}} 
\begin{itemize}
\item{Objetivo 1:} Desarrollo de un prototipo desechable de la funcionalidad básica de la herramienta.
\item{Objetivos cumplidos:} 1.
\end{itemize}

En esta fase el objetivo principal era el desarrollo de un prototipo desechable que mostrara el funcionamiento básico de la herramienta. Consideramos como funcionalidad básica la generación de fórmulas de restricciones de tablas SQL, sin incluir claves primarias ni claves ajenas, y sólo para atributos de tipo enteros. Para este prototipo no se realiza ninguna tarea de parsing, incluyendo las tablas SQL directamente en el código mediante la implementación de una primera estructura C++ para su representación. La única finalidad de este prototipo era que nos pudiéramos hacer una idea del trabajo que teníamos entre manos, pudiendo de esta forma realizar una planificación más exacta del resto de fases del desarrollo. Disponer de este prototipo antes de las vacaciones de Navidad era crucial para no retrasar más el desarrollo de la herramienta.

\item{\emph{Fase 1 de desarrollo: Primera versión}}
\begin{itemize}
\item{Objetivo 1:} Diseño e implementación de una estructura C++ extensible para la representación de tablas y vistas SQL.
\item{Objetivo 2:} Parsing de tablas SQL con atributos de tipo entero.
\item{Objetivo 3:} Parsing de definiciones de claves primarias y ajenas de tablas SQL.
\item{Objetivo 4:} Parsing de vistas con atributos de tipo entero y consultas simples (sin subconsultas).
\item{Objetivos cumplidos:} 1, 2, 3 y 4.
\end{itemize}

Esta fase se caracteriza por el diseño e implementación de una estructura C++ que represente tablas y vistas SQL. Esta representación debería permitir su extensión de forma fácil, pues en fases posteriores del desarrollo se tenía la intención de ampliar el lenguaje SQL aceptado. Además, de forma paralela, se comenzó a desarrollar el analizador SQL. Este analizador será el encargado de generar la estructura C++ de las tablas y vistas que el usuario introdujera a la herramienta mediante código SQL.

\item{\emph{Fase 2 de desarrollo: Segunda Versión:}}
\begin{itemize}
\item{Objetivo 1:} Extensión de la estructura en C++ para la inclusión de subconsultas existenciales anidadas.
\item{Objetivo 2:} Parsing de subconsultas existenciales anidadas.
\item{Objetivo 3:} Diseño de un modelo de representación las fórmulas lógicas de primer orden que representan restricciones.
\item{Objetivo 4:} Diseño e implementación del módulo de generación de fórmulas de restricciones para tablas y vistas SQL.
\item{Objetivo 5:} Generación de fórmulas de restricciones para tablas y vistas SQL, estas últimas con subconsultas existenciales.
\item{Objetivos cumplidos:} 1, 2, 3 y 4. El objetivo 5 se cumplió de forma parcial.
\end{itemize}

En esta fase cabe destacar la inclusión del módulo para la generación de fórmulas de restricciones para tablas y vistas SQL, y el diseño para la representación de estas. Este diseño debería ser lo suficientemente abstracto como para que pueda ser traducido al lenguaje de restricciones del resolutor que el usuario desee utilizar. Esta traducción simplemente requeriría un módulo extra en nuestra herramienta, de forma que tuviera como entrada las fórmulas generadas y las tradujera. El módulo de generación de fórmulas de restricciones es el más importante del desarrollo, pues es el que justifica la realización de este proyecto. También destaca la extensión del analizador SQL con la capacidad para reconocer subconsultas existenciales, así como la ampliación de la estructura C++ para la representación de estas. Como se ha indicado, el objetivo 5 de esta fase se consiguió de forma parcial, pues esta versión de la herramienta generaba fórmulas para tablas y vistas SQL, pero estas últimas, al contrario que el objetivo 4 indicaba, sin subconsultas existenciales. Esta situación fue debida a que en la teoría expuesta en \cite{flops2010}, se trata el problema de la generación de fórmulas para subconsultas existenciales de una forma limitada (la subconsulta debe formar parte de una conjunción). Ante esta situación, se nos platearon dos opciones:

\begin{enumerate}
\item Seguir con la teoría expuesta en \cite{flops2010}, especificando la limitación en cuanto a subconsultas existenciales.
\item Buscar una forma más general para el tratamiento de subconsultas existenciales.
\end{enumerate}

Elegimos la segunda opción, a pesar del riesgo que suponía no encontrar una solución al problema, y retrasar el desarrollo del proyecto en vano. Sin embargo, la motivación de resolver un problema de estas características, junto con la posibilidad de ofrecer una herramienta que fuera independiente de esa limitación, era muy estimulante.

\item{\emph{Fase 3 de desarrollo: Tercera versión}}
\begin{itemize}
\item{Objetivo 1:} Extender la estructura C++ para dar soporte a los operadores SQL de conjuntos \cod{UNION}  e \cod{INTERSECT} para consultas SQL.
\item{Objetivo 2:} Parsing de consultas con operadores SQL de conjuntos \cod{UNION} e \cod{INTERSECT}.
\item{Objetivo 3:} Generación de fórmulas para consultas con operadores SQL de conjuntos \cod{UNION} e \cod{INTERSECT}.
\item{Objetivo 4:} Investigar una solución alternativa a la presentada en \cite{flops2010} para el tratamiento de subconsultas existenciales.
\item{Objetivos cumplidos:} 1, 2, 3 y 4.
\end{itemize}

En esta fase se continua ampliando el lenguaje SQL aceptado por el analizador SQL y la estructura C++ mediante la inclusión de consultas con los operadores de conjuntos \cod{UNION} e \cod{INTERSECT}, y su correspondiente generación de fórmulas de restricciones que contemplan este tipo de consultas. Sin embargo, el principal objetivo de esta fase era encontrar un solución alternativa a la expuesta en \cite{flops2010} para la generación de fórmulas de restricciones de consultas SQL que incluyan subconsultas existenciales anidadas. El resultado de esta investigación puede consultarse en \cite{prole2012}.

\item{\emph{Fase 4 de desarrollo: Cuarta versión}}
\begin{itemize}
\item{Objetivo 1:} Generación de fórmulas de restricciones para vistas SQL con subconsultas existenciales anidadas.
\item{Objetivo 2:} Generación de fórmulas de claves primarias y foráneas de tablas SQL.
\item{Objetivo 3:} Traducción de nuestro modelo de fórmulas de lógica de primer orden a resolutor específico.
\item{Objetivos cumplidos:} 1, 2 y 3.
\end{itemize}

Con la posibilidad de generar fórmulas de restricciones para subconsultas existenciales anidadas y claves primarias y ajenas de tablas SQL, completamos un gran paso en cuanto al conjunto de lenguaje SQL aceptado y usabilidad de la herramienta, por lo que decidimos empezar a generar los casos de prueba, objetivo final del proyecto. 
Los casos de prueba resultan de la resolución de las fórmulas de restricciones, que hasta entonces, genera la herramienta. Como se mencionó en la sección de investigación \ref{subsec:investigacion}, la resolución de restricciones es un campo ampliamente investigado, lo que permite disponer de resolutores de gran rendimiento de software libre. Inicialmente se propuso que utilizáramos el reputado resolutor de restricciones Gecode \cite{Gecode}. Sin embargo, la curva de aprendizaje de este resolutor resultó ser demasiado pronunciada, pues no es una herramienta trivial, dado su bajo nivel del abstracción, y el tiempo del que disponíamos era reducido. Por lo tanto, se buscaron alternativas, encontrando en MiniZinc \cite{MiniZinc} la más adecuada.

 MiniZinc es un lenguaje de modelado de restricciones que permite la representación de problemas de restricciones. MiniZinc nos ofrecía una forma más abstracta y cercana a nuestra representación interna que Gecode para la traducción de las fórmulas de restricciones, haciendo que la curva de aprendizaje fuera mucho menos pronunciada en comparación con la de Gecode. Además, la última distribución de MiniZinc incluye el resolutor de restricciones \emph{G12/CPX}, por lo que podíamos ejecutar directamente los modelos de MiniZinc resultantes de la traducción de la fórmulas de restricciones. Cabe resaltar que MiniZinc, o su versión de más bajo nivel \emph{FlatZinc} (la última distribución de MiniZinc incorpora conversores de MiniZinc a FlatZinc), es un lenguaje de modelado de restricciones aceptado como entrada por un gran número de resolutores, incluido el propio Gecode. Esta característica de MiniZinc y FlatZinc fue muy importante a la hora de tomar la decisión de utilizarlo como lenguaje de restricciones, pues dota a nuestra herramienta de poder ejecutar el modelo generado sobre el resolutor que el usuario considere más adecuado. Algunos resolutores de restricciones que implementan MiniZinc o FlatZinc como lenguaje de restricciones son: G12/CPX, Gecode \cite{Gecode}, ECLiPSE, SICtus Prolog, JaCoP, SCIP.

\end{enumerate}
